#include <kernel.h>

struct dde_kit_sem
{
	 semaphore_t sem;
};

/**
 * Initialize DDE kit semaphore
 *
 * \param  value  initial semaphore counter
 *
 * \return        pointer to new semaphore
 */
dde_kit_sem_t *
LD_SYM(dde_kit_sem_init)(int value)
{
	 dde_kit_sem_t *result = (dde_kit_sem_t *)ekf_alloc(sizeof(struct dde_kit_sem));
	 if (result == NULL)
	 {
		  return NULL;
	 }
	 semaphore_init(&result->sem, value);
	 // LD_SYM(dde_kit_printf)("create sem %08x, value = %d!\n", result->sem, value);
	 return result;
}

/**
 * Deinitialize semaphore
 *
 * \param  sem  semaphore reference
 */
void
LD_SYM(dde_kit_sem_deinit)(dde_kit_sem_t *sem)
{
	 // LD_SYM(dde_kit_printf)("deinit sem %08x\n", sem->sem);
	 ekf_free(sem);
}

/**
 * Acquire semaphore
 *
 * \param  sem  semaphore reference
 */
void
LD_SYM(dde_kit_sem_down)(dde_kit_sem_t *sem)
{
	 // LD_SYM(dde_kit_printf)("down sem %08x!\n", sem->sem);
	 semaphore_acquire(&sem->sem, NULL, NULL);
}

/**
 * Acquire semaphore (non-blocking)
 *
 * \param  sem  semaphore reference
 *
 * \return      semaphore state
 * \retval 0    semaphore was acquired
 * \retval !=0  semaphore was not acquired
 */
int
LD_SYM(dde_kit_sem_down_try)(dde_kit_sem_t *sem)
{
	 return semaphore_try_acquire(&sem->sem);
}

/**
 * Acquire semaphore (with timeout)
 *
 * \param  sem      semaphore reference
 * \param  timeout  timeout (in ms)
 *
 * \return          semaphore state
 * \retval 0        semaphore was acquired
 * \retval !=0      semaphore was not acquired
 */
//int LD_SYM(dde_kit_sem_down_timed)(dde_kit_sem_t *sem, int timout);

/**
 * Release semaphore
 *
 * \param  sem  semaphore reference
 */
void
LD_SYM(dde_kit_sem_up)(dde_kit_sem_t *sem)
{
	 // LD_SYM(dde_kit_printf)("up sem %08x!\n", sem->sem);
	 semaphore_release(&sem->sem);
}

#if DK_EXPORT_SYM

void
dde_kit_sem_symbol(void)
{
	 elf_mod_export_symbol("dde_kit_sem_init", &dde_kit_sem_init, 1);
	 elf_mod_export_symbol("dde_kit_sem_deinit", &dde_kit_sem_deinit, 1);
	 elf_mod_export_symbol("dde_kit_sem_down", &dde_kit_sem_down, 1);
	 elf_mod_export_symbol("dde_kit_sem_down_try", &dde_kit_sem_down_try, 1);
	 elf_mod_export_symbol("dde_kit_sem_up", &dde_kit_sem_up, 1);
}

#endif
